package com.pig4cloud.pig.ads.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URI;
import java.util.*;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.ads.gdt.service.GdtAccesstokenService;
import com.pig4cloud.pig.ads.gdt.service.GdtAdvertiserService;
import com.pig4cloud.pig.ads.pig.mapper.AdPicturePlatformMapper;
import com.pig4cloud.pig.ads.pig.mapper.PictureMapper;
import com.pig4cloud.pig.ads.service.AdPicturePlatformService;
import com.pig4cloud.pig.ads.service.AdvService;
import com.pig4cloud.pig.ads.service.TtAccesstokenService;
import com.pig4cloud.pig.ads.utils.OEHttpUtils;
import com.pig4cloud.pig.api.dto.AdPlanPictureLibDto;
import com.pig4cloud.pig.common.security.util.SecurityUtils;

import com.pig4cloud.pig.api.util.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.pig4cloud.pig.api.entity.AdPicturePlatform;
import com.pig4cloud.pig.api.entity.PictureLib;
import com.pig4cloud.pig.api.entity.ResponseBean;
import com.pig4cloud.pig.api.vo.PictureLibVo;
import com.pig4cloud.pig.common.core.util.R;

import lombok.extern.log4j.Log4j2;

/**
 * @description: 投放平台上传图片信息
 * @author: nml
 * @time: 2020/11/6 15:46
 **/
@Log4j2
@Service
public class AdPicturePlatformServiceImpl extends ServiceImpl<AdPicturePlatformMapper, AdPicturePlatform> implements AdPicturePlatformService {

	@Autowired
	private AdPicturePlatformMapper adPicturePlatformMapper;

	@Autowired
	private PictureMapper pictureMapper;

	@Autowired
	private TtAccesstokenService ttAccesstokenService;

	@Autowired
	private AdvService advService;

	@Autowired
	private AdPicturePlatformService adPicturePlatformService;

	@Autowired
	private GdtAdvertiserService gdtAdvertiserService;

	@Autowired
	private GdtAccesstokenService gdtAccesstokenService;

	@Value(value = "${gdt_url}")
	private String gdtUrl;

	/**
	 * 添加图片文件
	 */
	@Value(value = "${gdt_images_add_url}")
	private String gdtImagesAddUrl;

	/**
	 * 推送图片：头条/广点通
	 *
	 * @param req
	 * @return
	 */
	@Override
	public R pushPic(PictureLibVo req) {
		if (StringUtils.isBlank(req.getPids())) {
			return R.failed(null, "未获取到图片ID");
		}
		if (null == req.getPlatformType()) {
			return R.failed(null, "未获取到平台类型");
		}
		if (null == req.getAdvertiserIds() || req.getAdvertiserIds().length == 0){
			return R.failed(null,"未获取到广告账户");
		}

		if (req.getPlatformType() == 1) {
			return synPictureBatch(req);//头条
		} else if (req.getPlatformType() == 2) {
			return uploadPicGdt(req);//广点通
		}
		return R.failed("无效的平台ID");
	}

	//广点通：批量推送图片方法
	@Override
	public R uploadPicGdt(PictureLibVo req) {
		//图片id数组
		String[] idsGroup = req.getPids().split(",");

		//获取多个广告账户id集合
		List<String> advertiserIdsList = Arrays.asList(req.getAdvertiserIds());
		//遍历图片ids
		for (String pid : idsGroup) {
			PictureLib pictureLib = pictureMapper.selectById(pid);
			if (null != pictureLib) {
				//制作人ID
				String createUser = pictureLib.getCreator();
				if (StringUtils.isBlank(createUser)) {
					return R.failed(null, "未获取到制作人ID");
				}

				if (null != advertiserIdsList && !advertiserIdsList.isEmpty()) {
					String msg = "";
					String upload_type = "UPLOAD_TYPE_FILE";
					//遍历所选的广告账户id
					for (int i = 0; i < advertiserIdsList.size(); i++) {
						//获取当前广告账户id
						String advertiserId = advertiserIdsList.get(i);
						//公共方法获取accessToken
						Map<String, String> map = gdtAccesstokenService.fetchAccesstoken(advertiserId);
						//定义广点通接口url
						String url = gdtUrl + gdtImagesAddUrl + "?" + MapUtils.queryString(map);
						Map<String, Object> params = new HashMap<String, Object>();
						params.put("account_id", advertiserId);
						params.put("upload_type", upload_type);
						params.put("signature", pictureLib.getMd5());
						params.put("realPath", pictureLib.getRealPath());
						//调第三方平台（头条）接口
						JSONObject resultStr = synPicGdtPost(url, params);
						ResponseBean resBean = JSON.parseObject(resultStr.toJSONString(), ResponseBean.class);
						//调用成功
						if (resBean != null && resBean.getCode() != null && "0".equals(resBean.getCode())) {
							Map<String, Object> picData = resBean.getData();
							AdPicturePlatform adp = new AdPicturePlatform();
							adp.setPictureId(Long.parseLong(pictureLib.getId() + ""));
							adp.setPlatformId(3);//3:广点通
							adp.setPlatformName("gdt");
							adp.setAdvertiserId(advertiserId);//广告账户
							//图片类型（头条要求的）固定先
							adp.setPictureType(0);
							adp.setPlatformPictureId(String.valueOf(picData.get("image_id")));
							adp.setPlatformPictureSize(Integer.parseInt(String.valueOf(picData.get("file_size"))));
							adp.setPlatformPictureWidth(Integer.parseInt(String.valueOf(picData.get("width"))));
							adp.setPlatformPictureHeight(Integer.parseInt(String.valueOf(picData.get("height"))));
							adp.setPlatformPictureFormat(String.valueOf(picData.get("type")));
							adp.setPlatformPictureSignature(String.valueOf(picData.get("signature")));
							adp.setPlatformPictureUrl(String.valueOf(picData.get("preview_url")));
							adp.setPictureType(getPicType(String.valueOf(picData.get("width")),String.valueOf(picData.get("height"))));

							adp.setUpdateTime(new Date());
							adp.setCreateTime(new Date());

							int count = adPicturePlatformService.count(Wrappers.<AdPicturePlatform>query().lambda().eq(AdPicturePlatform::getPictureId, pictureLib.getId())
									.eq(AdPicturePlatform::getAdvertiserId, advertiserId));
							//如果图片推送表中没有当前图片及当前广告账户的推送信息，则保存信息
							if (count == 0) {
								adPicturePlatformService.save(adp);
							}
							log.info(">>>广点通图片ID:{} >>>预览地址:{}", String.valueOf(picData.get("image_id")), String.valueOf(picData.get("preview_url")));
							log.info(">>>图片ID:{}，上传广点通账户:{}，成功", pictureLib.getId(), advertiserId);
						} else {
							msg = ">>>图片ID：" + pictureLib.getId() + "，上传广点通账户：" + advertiserId + "，失败，原因：" + resBean.getMessage();
							break;
						}
					}

					if (StringUtils.isNotBlank(msg)) {
						log.info(msg);
						return R.failed(null, msg);
					}
				} else {
					log.error(">>>未获取到广告账户");
					return R.failed(null, "未获取到广告账户");
				}
			} else {
				log.error(">>>未获取到图片");
				return R.failed(null, "未获取到图片");
			}
		}

		//当从广告创意处同步图片时，查询到一条图片推送信息记录
		req.setCurrent(1);
		req.setSize(1);
		//图片id数组
		String id1 = idsGroup[0];
		req.setId(Integer.parseInt(id1));//设置图片id
		//获取多个广告账户id集合
		String advertiserId1 = advertiserIdsList.get(0);
		req.setAdvertiserId(advertiserId1);//设置广告账户id
		//查询一张图片推送信息
		AdPlanPictureLibDto data = pictureMapper.selectAdPlanPicSynData(req);
		log.info(">>>操作成功");
		return R.ok(data, "操作成功");
	}

	//广点通：推送图片 请求
	public static JSONObject synPicGdtPost(String url, Map<String, Object> data) {
		// 构造请求
		HttpPost httpPost = new HttpPost(url);
		// 文件参数
		FileBody file = new FileBody(new File(String.valueOf(data.get("realPath"))));
		MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create()
				.addPart("file", file);
		// 其他参数
		entityBuilder.addTextBody("account_id", String.valueOf(data.get("account_id")));
		entityBuilder.addTextBody("upload_type", String.valueOf(data.get("upload_type")));
		entityBuilder.addTextBody("signature", String.valueOf(data.get("signature")), ContentType.APPLICATION_JSON);
		HttpEntity entity = entityBuilder.build();
		CloseableHttpResponse response = null;
		CloseableHttpClient client = null;
		try {
			client = HttpClientBuilder.create().build();
			httpPost.setURI(URI.create(url));

			httpPost.setEntity(entity);

			response = client.execute(httpPost);
			if (response != null && response.getStatusLine().getStatusCode() == 200) {
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
				StringBuffer result = new StringBuffer();
				String line = "";
				while ((line = bufferedReader.readLine()) != null) {
					result.append(line);
				}
				bufferedReader.close();
				return JSONObject.parseObject(result.toString());
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return new JSONObject();
	}

	//头条：批量推送图片
	@Override
	public R synPictureBatch(PictureLibVo pictureLibVo) {
		//通过creator去查询多个广告主id
		Integer id = SecurityUtils.getUser().getId();
		//获取当前账号下 广告账户列表
		List<String> allList = advService.getOwnerAdv(id, pictureLibVo.getPlatformId());
		if(allList == null || allList.isEmpty()) {
			return R.failed("当前登录账户下无广告账户");
		}
		//图片id不能为空
		if (StringUtils.isBlank(pictureLibVo.getPids())){
			return R.failed("请选择同步图片");
		}
		//广告账户id不能为空
		if (Objects.isNull(pictureLibVo.getAdvertiserIds()) || pictureLibVo.getAdvertiserIds().length<=0){
			return R.failed("广告账户id不能为空");
		}
		//获取多个图片id
		String pids = pictureLibVo.getPids();
		String[] pidArr = pids.split(",");
		List<Integer> pidList = Lists.newArrayList();
		//获取多个广告账户id集合
		List<String> advertiserIdsList = Arrays.asList(pictureLibVo.getAdvertiserIds());

		//循环图片id，同步图片
		for (int i = 0; i < pidArr.length; i++) {
			int picId = Integer.parseInt(pidArr[i]);
			PictureLib pictureLib = pictureMapper.selectById(picId);
			pictureLibVo.setId(Integer.parseInt(pidArr[i]));
			boolean synStatus = synPicture(pictureLib,advertiserIdsList);
			//如果同步失败则添加到集合
			if (!synStatus){
				pidList.add(Integer.parseInt(pidArr[i]));
			}
		}
		//判断同步成功与否
		//部分图片未同步成功,返回未同步成功的图片名给前端
		if (!pidList.isEmpty()){
			List<String> pictureNameList = Lists.newArrayList();
			for (int i = 0; i < pidList.size(); i++) {
				PictureLib pictureLib = pictureMapper.selectById(pidList.get(i));
				pictureNameList.add(pictureLib.getPictureName());
			}
			return R.failed(pictureNameList,"{"+pictureNameList.toString()+"}:同步失败");
		}

		//当从广告创意处同步图片时，查询到一条图片推送信息记录
		pictureLibVo.setCurrent(1);
		pictureLibVo.setSize(1);
		AdPlanPictureLibDto data = pictureMapper.selectAdPlanPicSynData(pictureLibVo);

		//全部同步成功
		return R.ok(data,"所选图片全部同步成功");
	}

	//头条：推送图片方法
	@Override
	public boolean synPicture(PictureLib pictureLib,List<String> allList){
		//根据id查到图片信息
		Integer id = pictureLib.getId();
		String upload_type = "UPLOAD_BY_URL";
		String image_url = pictureLib.getPictureUrl();
		String filename = pictureLib.getPictureName();
		//定义头条接口url
		String url = "https://ad.oceanengine.com/open_api/2/file/image/ad/";

		//同步返回信息，待入库集合
		List<AdPicturePlatform> adPicturePlatformList = Lists.newArrayList();
		int count = 0;
		//集合不为null且size不为0
		if (allList != null && !allList.isEmpty()){
			for (int i = 0; i < allList.size(); i++) {
				String advertiser_id = allList.get(i);
				Map<String, Object> data = new HashMap<String, Object>();
				data.put("advertiser_id", advertiser_id);
				data.put("upload_type",upload_type);
				data.put("image_url",image_url);
				data.put("filename",filename);
				//公共方法获取accessToken
				String accessToken = ttAccesstokenService.fetchAccesstoken(advertiser_id);
				//调第三方平台（头条）接口
				String resultStr = OEHttpUtils.doPost(url, data, accessToken);
				ResponseBean resBean = JSON.parseObject(resultStr, ResponseBean.class);
				//调用成功
				if(resBean != null && "0".equals(resBean.getCode())){
					//new一个投放平台图片状态类：头条
					AdPicturePlatform adPicturePlatform = new AdPicturePlatform();
					long pid = Long.parseLong(id + "");
					adPicturePlatform.setPictureId(pid);
					adPicturePlatform.setPlatformId(1);
					adPicturePlatform.setPlatformName("tt");
					adPicturePlatform.setAdvertiserId(advertiser_id);
					adPicturePlatform.setCreateTime(new Date());
					adPicturePlatform.setUpdateTime(new Date());
					AdPicturePlatform lp = getPostPicResp(resBean, adPicturePlatform);
					adPicturePlatformList.add(lp);
					count++;
				}
				log.info(">>>调用头条接口结果：{}",resultStr);
			}
		}else {
			//没有可上传的广告账户id
			return false;
		}
		log.info(">>>当前登录账号下广告账户id数量：{}",allList.size());
		log.info(">>>调用头条接口成功次数：{}",count);
		//判断是否全部同步成功
		if (allList.size()==count){
			List<AdPicturePlatform> adPicturePlatformSynList = Lists.newArrayList();
			for (int i = 0; i < adPicturePlatformList.size(); i++) {
				//取到推送成功的图片信息
				Long pictureId = adPicturePlatformList.get(i).getPictureId();
				String advertiserId = adPicturePlatformList.get(i).getAdvertiserId();
				//根据图片id和广告账户id查询 图片推送信息表，如果未查询到则推送，查到记录则不推送。
				AdPicturePlatform picPlatform = adPicturePlatformMapper.selectOne(Wrappers.<AdPicturePlatform>query().lambda()
						.eq(AdPicturePlatform::getPictureId, pictureId)
						.eq(AdPicturePlatform::getAdvertiserId, advertiserId)
						.last("LIMIT 1"));
				if (null == picPlatform){
					adPicturePlatformSynList.add(adPicturePlatformList.get(i));
				}
			}
			//集合size=0，直接返回true
			if (adPicturePlatformSynList.isEmpty()){
				return true;
			}
			//全部同步成功，信息入库
			this.saveBatch(adPicturePlatformSynList);
			//同步成功，信息入库成功
			return true;
		}
		//同步失败
		return false;
	}

	//获取图片同步上传返回信息
	public static AdPicturePlatform getPostPicResp(ResponseBean resBean, AdPicturePlatform adPicturePlatform){
		//如果当前广告账号id调用成功，返回信息入数据库
		JSONObject jsonObj = resBean.getData();
		String platform_picture_id = jsonObj.getString("id"); //获取第三方平台的 图片ID
		String size = jsonObj.getString("size");
		String width = jsonObj.getString("width");
		String height = jsonObj.getString("height");
		String platform_picture_url = jsonObj.getString("url");
		String format = jsonObj.getString("format");
		String signature = jsonObj.getString("signature");
		String material_id = jsonObj.getString("material_id");
		adPicturePlatform.setPlatformPictureId(platform_picture_id);
		adPicturePlatform.setPlatformPictureFormat(format);
		int height1 = Integer.parseInt(height);
		int  width1 = Integer.parseInt(width);
		//获取图片类型
		int type = getPicType(width,height);
		adPicturePlatform.setPictureType(type);
		adPicturePlatform.setPlatformPictureHeight(height1);
		adPicturePlatform.setPlatformPictureWidth(width1);
		adPicturePlatform.setPlatformPictureSize(Integer.parseInt(size));
		adPicturePlatform.setPlatformPictureMaterialId(material_id);
		adPicturePlatform.setPlatformPictureSignature(signature);
		adPicturePlatform.setPlatformPictureUrl(platform_picture_url);
		return adPicturePlatform;
	}

	//获取到图片类型
	public static int getPicType(String widthParam,String heightParam){
		double width = Double.parseDouble(widthParam);
		double height = Double.parseDouble(heightParam);
		double ratio = width/height;
		BigDecimal bRatio = new BigDecimal(ratio);
		double ratio2 = bRatio.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		//其他类型：others
		int type = 0;
		if (1.52 == ratio2 && width >= 456 && width <= 1368 && height >= 300 && height <= 900){
			//小图
			type = 1;
		}else if (1.78 == ratio2 && width >= 1280 && width <= 2560 && height >= 720 && height <= 1440){
			//横版大图
			type = 2;
		}else if (0.56 == ratio2  && width >= 720 && width <= 1440 && height >= 1280 && height <= 2560){
			//竖版大图
			type = 3;
		}else if (690 == width && 388 == height){
			//gif图
			type = 4;
		}else if (108 == width && 108 == height){
			//卡片主图
			type = 5;
		}
		return type;
	}


	/*	@Override
	public R synGdtPictureBatch(PictureLibVo pictureLibVo) {
		boolean b = synGdtPicture(pictureLibVo.getId());
		if (b){
			return R.ok("推送成功");
		}
		return R.failed("推送失败");
	}

	//同步广点通图片方法
	public boolean synGdtPicture(Integer id){
		Integer account_id = 17209785;
		String upload_type = "UPLOAD_TYPE_FILE";
		//根据id查到图片信息
		PictureLib pictureLib = pictureMapper.selectById(id);
		String signature = "a219dc179ceb4f84272ff0555f062b21";
		//公共方法获取accessToken
		//String accessToken = ttAccesstokenService.fetchAccesstoken(advertiser_id);
		String accessToken = "33a5282a5e445641ae529f1796cecac0";
		String a = UUID.randomUUID().toString();
		String nonce = a.replaceAll("-", "");
		long timestamp = DateUtils.Date2TimeStampLong(new Date());
		//定义广点通接口url
		String url = "https://api.e.qq.com/v1.1/images/add"+"?access_token=33a5282a5e445641ae529f1796cecac0&timestamp="+timestamp+"&nonce="+nonce;

		Map<String, Object> data = new HashMap<String, Object>();
		data.put("account_id", account_id);
		data.put("upload_type",upload_type);
		data.put("signature",signature);
		data.put("realPath","D:\\upload\\横版大图101.jpg");

		JSONObject jsonObject = SynPicGdtPost(url, data);
		log.info("调用广点通接口结果：{}",jsonObject);
		return false;
	}*/

}
